package com.smart.community.work.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;

/**
 * 安保路线更新DTO
 * 
 * 严格按照《Java后端SpringBoot代码开发规范_重构版.md》DTO规范实现：
 * - 功能单一原则：DTO类必须是单纯的数据传输对象，功能必须单一
 * - 参数验证：使用JSR-303注解进行参数验证
 * - 完整注释：所有字段都有完整的JavaDoc注释
 * - 字段映射：字段名与前端表单字段名保持一致
 * - 数据格式：使用合适的数据类型，避免使用枚举类
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 * @version 1.0.0
 */
@Data
@Schema(description = "安保路线更新DTO")
public class SecurityRouteUpdateDTO {

    /**
     * 路线ID
     */
    @NotNull(message = "路线ID不能为空")
    @Schema(description = "路线ID", example = "1")
    private Long id;

    /**
     * 路线名称
     */
    @NotBlank(message = "路线名称不能为空")
    @Size(max = 100, message = "路线名称长度不能超过100个字符")
    @Schema(description = "路线名称", example = "A区巡逻路线")
    private String routeName;

    /**
     * 路线类型：patrol-巡逻，checkpoint-检查点
     */
    @NotBlank(message = "路线类型不能为空")
    @Schema(description = "路线类型", example = "patrol", allowableValues = {"patrol", "checkpoint"})
    private String routeType;

    /**
     * 路线描述
     */
    @Size(max = 500, message = "路线描述长度不能超过500个字符")
    @Schema(description = "路线描述", example = "负责A区主要通道的巡逻检查")
    private String description;

    /**
     * 检查点列表
     */
    @Schema(description = "检查点列表")
    private List<CheckpointDTO> checkpoints;

    /**
     * 自定义setter方法，处理前端传递的JSON字符串格式的checkpoints数据
     * 
     * @param checkpointsData 检查点数据，可以是List<CheckpointDTO>或JSON字符串
     */
    @JsonProperty("checkpoints")
    public void setCheckpoints(Object checkpointsData) {
        if (checkpointsData == null) {
            this.checkpoints = null;
            return;
        }
        
        try {
            if (checkpointsData instanceof String) {
                // 如果是字符串，尝试解析为JSON
                String jsonString = (String) checkpointsData;
                if (jsonString.trim().isEmpty()) {
                    this.checkpoints = new ArrayList<>();
                    return;
                }
                
                ObjectMapper objectMapper = new ObjectMapper();
                // 使用JavaType来避免TypeReference的类加载问题
                JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(List.class, CheckpointDTO.class);
                this.checkpoints = objectMapper.readValue(jsonString, javaType);
            } else if (checkpointsData instanceof List) {
                // 如果已经是List，直接赋值
                @SuppressWarnings("unchecked")
                List<CheckpointDTO> checkpointList = (List<CheckpointDTO>) checkpointsData;
                this.checkpoints = checkpointList;
            } else {
                // 其他类型，尝试转换为List
                this.checkpoints = new ArrayList<>();
            }
        } catch (JsonProcessingException e) {
            // JSON解析失败，记录日志并设置为空列表
            System.err.println("解析checkpoints JSON字符串失败: " + e.getMessage());
            this.checkpoints = new ArrayList<>();
        } catch (Exception e) {
            // 其他异常，记录日志并设置为空列表
            System.err.println("处理checkpoints数据失败: " + e.getMessage());
            this.checkpoints = new ArrayList<>();
        }
    }

    /**
     * 巡逻频次：hourly-每小时，every_2_hours-每2小时，daily-每日
     */
    @NotBlank(message = "巡逻频次不能为空")
    @Schema(description = "巡逻频次", example = "daily", allowableValues = {"hourly", "every_2_hours", "daily"})
    private String frequency;

    /**
     * 预计用时（分钟）
     */
    @Schema(description = "预计用时（分钟）", example = "60")
    private Integer durationMinutes;

    /**
     * 所属社区ID
     */
    @NotNull(message = "所属社区不能为空")
    @Schema(description = "所属社区ID", example = "1")
    private Long communityId;

    /**
     * 状态：1-启用，2-停用
     */
    @Schema(description = "状态", example = "1", allowableValues = {"1", "2"})
    private Integer status;

    /**
     * 检查点DTO
     */
    @Data
    @Schema(description = "检查点DTO")
    public static class CheckpointDTO {

        /**
         * 检查点名称
         */
        @NotBlank(message = "检查点名称不能为空")
        @Size(max = 100, message = "检查点名称长度不能超过100个字符")
        @Schema(description = "检查点名称", example = "大门检查点")
        private String name;

        /**
         * 检查点描述
         */
        @Size(max = 200, message = "检查点描述长度不能超过200个字符")
        @Schema(description = "检查点描述", example = "检查大门安全状况")
        private String description;
    }
}
